package com.geekhalo.admin.domain.user;

import com.geekhalo.admin.domain.user.changePassword.ChangePasswordCommand;
import com.geekhalo.admin.domain.user.changePassword.ChangePasswordContext;
import com.geekhalo.admin.domain.user.changePassword.ChangePasswordContext;
import com.geekhalo.admin.domain.user.changePassword.PasswordChangedEvent;
import com.geekhalo.admin.domain.user.create.CreateUserCommand;
import com.geekhalo.admin.domain.user.create.CreateUserContext;
import com.geekhalo.admin.domain.user.create.CreateUserContext;
import com.geekhalo.admin.domain.user.create.UserCreatedEvent;
import com.geekhalo.admin.domain.user.disable.DisableUserCommand;
import com.geekhalo.admin.domain.user.disable.DisableUserContext;
import com.geekhalo.admin.domain.user.disable.DisableUserContext;
import com.geekhalo.admin.domain.user.disable.UserDisabledEvent;
import com.geekhalo.admin.domain.user.enable.EnableUserCommand;
import com.geekhalo.admin.domain.user.enable.EnableUserContext;
import com.geekhalo.admin.domain.user.enable.EnableUserContext;
import com.geekhalo.admin.domain.user.enable.UserEnabledEvent;
import com.geekhalo.admin.domain.user.update.UpdateUserCommand;
import com.geekhalo.admin.domain.user.update.UpdateUserContext;
import com.geekhalo.admin.domain.user.update.UpdateUserContext;
import com.geekhalo.admin.domain.user.update.UserUpdatedEvent;
import com.geekhalo.lego.core.command.support.AbstractAggRoot;
import lombok.AccessLevel;
import lombok.Data;
import lombok.NoArgsConstructor;
import lombok.Setter;

import javax.persistence.*;

@Entity
@Table(name = "user")
@Data
@NoArgsConstructor(access = AccessLevel.PROTECTED)
@Setter(AccessLevel.PRIVATE)
public class User extends AbstractAggRoot { 
    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Long id;

    private UserStatus status;

    private String loginName;

    private String loginPassword;

    private String showName;


    public static User create(CreateUserContext context) {
        User agg = new User();
        agg.readFrom(context.getCommand());
        agg.init();
        return agg;
    }

	// 自动生成代码，勿动
	private void readFrom(CreateUserCommand source){
		if(source.getLoginName() != null){
			this.setLoginName(source.getLoginName());
		}
		if(source.getLoginPassword() != null){
			this.setLoginPassword(source.getLoginPassword());
		}
		if(source.getShowName() != null){
			this.setShowName(source.getShowName());
		}
	}

    private void init() {
        setStatus(UserStatus.DISABLED);
        addEvent(new UserCreatedEvent(this));
    }


    public void update(UpdateUserContext context) {
        this.readFrom(context.getCommand());
        addEvent(new UserUpdatedEvent(this));
    }

	// 自动生成代码，勿动
	private void readFrom(UpdateUserCommand source){
		if(source.getShowName() != null){
			this.setShowName(source.getShowName());
		}
	}

    public void enable(EnableUserContext context) {
        if (getStatus() == UserStatus.DISABLED) {
            setStatus(UserStatus.ENABLED);
            addEvent(new UserEnabledEvent(this));
        }
    }


    public void disable(DisableUserContext context) {
        if (getStatus() == UserStatus.ENABLED) {
            setStatus(UserStatus.DISABLED);
            addEvent(new UserDisabledEvent(this));
        }
    }


    public void changePassword(ChangePasswordContext context) {
        ChangePasswordCommand command = context.getCommand();
        if (!this.getLoginPassword().equals(command.getPassword())){
            throw new RuntimeException("密码错误");
        }
        setLoginPassword(command.getNewPassword());
        addEvent(new PasswordChangedEvent(this));
    }
}